/************************************************************************

								Heroes IV
					  Copyright 2000, The 3DO Company

	------------------------------------------------------------------
  						         transition_mask.h

	$Header: /resource_editor/transition_mask.h $

	$NoKeywords: $

 ************************************************************************/

#ifndef TRANSITION_MASK_H_INCLUDED
#define TRANSITION_MASK_H_INCLUDED

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000

#include <bitset>
#include <vector>
#include "adventure_tile_size.h"
#include "resource_traits.h"
#include "sized_int_types.h"
#include "static_vector.h"

// -------------------------------------------------------------------------------
// transition mask definition
// -------------------------------------------------------------------------------
class t_transition_mask 
{
public:
	t_transition_mask();
	t_transition_mask( t_transition_mask const& arg );
	~t_transition_mask();

	static int const k_column_start[k_adventure_tile_width];
	static int const k_column_stop[k_adventure_tile_width];

	void           create( int bits );
	int            get_bits() const;
	int            get_code() const;
	t_uint8*       get_column( int column );
	t_uint8 const* get_column( int column ) const;
	t_uint32       get_column_mask( int column ) const;
	bool           read( std::streambuf& buffer );
	void           set_code( int code );
	bool           write( std::streambuf& buffer ) const;
	t_transition_mask& operator=( t_transition_mask const& arg );
protected:
	int get_data_size() const;
	void copy( t_transition_mask const& arg );

	static int const k_offsets[2][k_adventure_tile_width];

	int      m_code;
	t_uint8  m_bits; // 1 or 4.
	t_uint8* m_data;
};

inline int t_transition_mask::get_bits() const
{
	return m_bits;
}

inline void t_transition_mask::set_code( int code )
{
	m_code = code;
}

inline int t_transition_mask::get_code() const
{
	return m_code;
}

inline t_uint8* t_transition_mask::get_column( int column )
{
	return m_data + k_offsets[m_bits == 4][column];
}

inline t_uint8 const* t_transition_mask::get_column( int column ) const
{
	return m_data + k_offsets[m_bits == 4][column];
}

// get data as a column of bits - only works for 1 bit masks
inline t_uint32 t_transition_mask::get_column_mask( int column ) const
{
	if (column > 60)
		return *get_column( column );
	return *(reinterpret_cast<t_uint32 const*>( get_column( column ) ));
}

inline int t_transition_mask::get_data_size() const
{
	return k_offsets[m_bits == 4][k_adventure_tile_width - 1] + 1;
}

// -------------------------------------------------------------------------------
// set of transition masks
// -------------------------------------------------------------------------------
class t_transition_set : public std::vector<t_transition_mask>
{
public:
	std::string get_name() const;
	void        set_name( std::string const& name );

	bool read( std::streambuf& buffer );
	bool write( std::streambuf& buffer) const;
protected:
	std::string m_name;
};

inline std::string t_transition_set::get_name() const
{
	return m_name;
}

inline void t_transition_set::set_name( std::string const& name )
{
	m_name = name;
}

// -------------------------------------------------------------------------------
// array of transition sets
// -------------------------------------------------------------------------------
class t_transition_set_array : public std::vector<t_transition_set>
{
};

template <>
struct t_resource_traits<t_transition_set_array>
{
	static char const prefix[];
	static char const extension[];
};


bool read( std::streambuf& buffer, t_transition_set_array& mask );
bool write( std::streambuf& buffer, t_transition_set_array const& mask );

#endif // TRANSITION_MASK_H_INCLUDED